import { EventEmitter, on } from "events";
import { app } from 'electron'
import path from 'path';
import fs from 'fs';
import { createConnection, DataSource  } from "typeorm";
import Entitys from "../entity/index";
import camelcase from "camelcase"

declare type ValueObject = {
    [key: string]: any
    connection : DataSource
    pluginPath: string
} 
const entities:Array<any>= Entitys
class Globals extends EventEmitter{

    private values: ValueObject | {[key: string]: any} = { }
    private _initValues(){
        this.on('init-plugin-path', ()=>{
            if( typeof this.values.pluginPath === 'undefined'){
                const pluginPath = path.resolve( path.dirname( app.getPath('exe') ), 'plugins')
                if( fs.existsSync( pluginPath )){
                    this.values.pluginPath = pluginPath
                }else {
                    this.values.pluginPath = "src/plugins"
                }
            }
        })
        this.on('init-connection', this._init_connection)
    }

    private isDefined( key: string ){
        return typeof this.values[key] !== 'undefined' 
    }

    constructor(){
        super({captureRejections: true})
        this.values = {}
        this._initValues()
    }

    private _init_connection(){
        if( this.isDefined('connection')) return this.values.connection;
        const init = ()=>{
            return new Promise(( resolve , reject )=>{
                createConnection({
                    type: 'sqlite',
                    database: 'src/backend/data/data.db',
                    entities: entities,
                    synchronize: true,
                    logging: 'all',
                    // synchronize: true
                })
                .then( res => {
                    resolve( res )
                })
                .catch( err => { throw new Error('Cannot init the database') })
            })
        }
        const g = async ()=>{
            return await init()
        }
        return this.values.connection = g()
    }

    getGlobal( name: string ){
        this.emit( 'init-' + name )
        this.emit( 'get-some-value', name )
        this.emit( 'get-some-value-' + name )
        return this.values[camelcase(name)]
    }

    setGlobal( name: string, value: any){
        const old = this.values[name]
        this.emit( 'before-change-value-'+ name, value, old )
        this.emit( 'before-change-value', value, old, name )
        this.values[camelcase(name)] = value
        this.emit( 'after-change-value-'+ name, value, old )
        this.emit( 'after-change-value', value, old, name )
        return this.values[camelcase(name)]
    }
}

export default new Globals()